<?php
/**
 * Classe déléguée à la gestion des formulaires
 *
 * @category librairies
 * @package sh
 *
 * @author Mickaël CASTANHEIRO
 * @version 1.0
 */
class shFormulaire extends shBase {
    /*
     * Constantes
     */
    const POST = 'post';
    const GET = 'get';

    /**
     * @access private
     * @var boolean
     */
    private $executed;

    /**
     * Champs du formulaire
     * @access protected
     * @var array
     */
    protected $fields;

    /**
     * Données de transit
     */
    protected $datas;

    /**
     * Liens et boutons additionnels
     */
    protected $buttons;

    /**
     * Attributs spéciaux pour le formulaire
     */
    protected $attributes;

    /**#@+
     * @access protected
     * @var string
     */
    protected $name;
    protected $method;
    protected $action;
    protected $submitText;
    protected $confirmation;
    /**#@-*/

    /**
     * @access protected
     * @var function
     */
    protected $check, $submit;

    /**
     * @access private
     */

    /**
     * Constructeur de la classe
     */
    public function __construct() {
	$this->method = shFormulaire::POST;
	$this->action = shRequest::__instance()->__toString();
	$this->submitText = 'Valider';
	$this->buttons = array();
	$this->attributes = array();
	$this->executed = false;
    }
   


    /**
     * Lie le champ à un formulaire
     * @param <sField> Champ à ajouter
     */
    public function append(shField $_field) {
	$this->fields[$_field->getName()] = $_field;
    }

    /*
     * Lie le bouton au formulaire
     * @param <shField> Bouton à ajouter
     */
    public function appendButton(shField $_field) {
	$this->buttons[$_field->getName()] = $_field;
    }

    /**
     * Retourne un champ
     * @param <string> Label du champ
     * @return <shField> Champ
     */
    public function getField($_label) {
        return $this->fields[escapeString($_label)];
    }

    /**
     * Indique si un champ existe
     * @param <string> Label du champ
     * @return <boolean> Existence du champ
     */
    public function isField($_label) {
        return (isset($this->fields[escapeString($_label)]) AND ($this->fields[escapeString($_label)] !== false));
    }

    /**
     * Indique si l'un des champs du formulaire a une erreur
     * @return <boolean>
     */
    public function isError() {
	foreach($this->fields AS $field) {
	    if ( $field->isError() ) return true;
	}
	return false;
    }

    /**
     * Alias de addData
     * @param <string> Nom de la variable
     * @param <mixed> Valeur
     */
    public function assign($_paramName, $_paramValue) {
        $this->addData($_paramName, $_paramValue);
    }

    /**
     * Alias de getData
     * @param <string> Nom de la variable
     * @return <mixed> Valeur
     */
    public function get($_paramName) {
	return $this->getData($_paramName);
    }

    /**
     * Ajoute un bouton ou un lien au formulaire
     * @param <
     */
    public function addButton($_type, $_label, $_module=null, $_action=null, $_request=null, $_arguments=null) {
	$button = new shField;
	$button->setType($_type);
	$button->setLabel($_label);
	$button->setName(escapeString($_label));
	$button->setValue(shRequest::link($_module, $_action, $_request, $_arguments));
	$this->buttons[] = $button;
    }

    /**
     * Exécute la soumission du formulaire
     */
    public function execute() {
	// Formulaire soumis
	if ( (!$this->executed) AND !empty($_POST['submit_'.escapeString($this->name)]) AND ($_POST['submit_'.escapeString($this->name)] == $this->submitText) ) {
	
    //Extraction des valeurs
	    foreach ($this->fields AS $field) {
		$field->execute();
	    }

	    // Erreurs ?
	    if ( isset($this->check) ) {
		$self = $this;
                $fn_check = $this->check;
                $fn_check($this);
	    }

	    if ( !$this->isError() ) {   
		if ( isset($this->submit) ) {
                   $self = $this;
                   $fn_submit = $this->submit;
                   $fn_submit($this);
		}
	    }

	    $this->executed = true;
	}
    }


    /**
     * Affichage du formulaire
     * @param <string> Template à parser
     */
    public function display($_template='_formulaire.tpl') {
	$this->execute();

	$template = new shTemplate;
	$template->addData('fields', $this->fields);

	// Si formulaire confirmé, afficher la confirmation
	if ( !empty($this->confirmation) ) {
	    $template->setPath(DIR_TEMPLATES . (($_template != '_formulaire.tpl') ? $_template : '_formulaireConfirmation.tpl') );
	    $template->addData('confirmation', $this->confirmation)
		     ->addData('link', shRequest::link(shRequest::__instance()->getModule(), shRequest::__instance()->getAction()));
	}
	
	// Sinon afficher le formulaire
	else {
	    $template->setPath(DIR_TEMPLATES . $_template);
	    $template->addData('buttons', $this->buttons)
		    ->addData('attributes', $this->attributes)
		    ->addData('method', $this->method)
		    ->addData('action', $this->action)
		    ->addData('name', $this->name)
		    ->addData('submitText', $this->submitText);
	}
	
	$template->display();
    }
}
?>